<?php
/**
 * tpshop 微信支付插件
 * ============================================================================
 * 版权所有 2015-2027 深圳搜豹网络科技有限公司，并保留所有权利。
 * 网站地址: http://www.tp-shop.cn
 * ----------------------------------------------------------------------------
 * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 * ============================================================================
 * Author: IT宇宙人
 * Date: 2015-09-09
 */

use Think\Model\RelationModel;
/**
 * 支付 逻辑定义
 * Class
 * @package Home\Payment
 */

class weixin extends RelationModel
{
    public $tableName = 'plugin'; // 插件表        
    public $alipay_config = array();// 支付宝支付配置参数

    /**
     * 析构流函数
     */
    public function  __construct() {
        parent::__construct();

        require_once("lib/WxPay.Api.php"); // 微信扫码支付demo 中的文件         
        require_once("example/WxPay.NativePay.php");
        require_once("example/WxPay.JsApiPay.php");

        $paymentPlugin = M('Plugin')->where("code='weixin' and  type = 'payment' ")->find(); // 找到微信支付插件的配置
        $config_value = unserialize($paymentPlugin['config_value']); // 配置反序列化
        WxPayConfig::$appid = $config_value['appid']; // * APPID：绑定支付的APPID（必须配置，开户邮件中可查看）
        WxPayConfig::$mchid = $config_value['mchid']; // * MCHID：商户号（必须配置，开户邮件中可查看）
        WxPayConfig::$key = $config_value['key']; // KEY：商户支付密钥，参考开户邮件设置（必须配置，登录商户平台自行设置）
        WxPayConfig::$appsecret = $config_value['appsecret']; // 公众帐号secert（仅JSAPI支付的时候需要配置)，
    }

    /*申请退款接口*/
    function wxRefund($order_id){


        //我的SDK放在项目根目录下的Api目录下
        //查询订单,根据订单里边的数据进行退款
        $order = M('order1')->where(array('order_id'=>$order_id))->find();

//		$merchid = WxPayConfig::MCHID;
        $merchid = WxPayConfig::$mchid;
        if(!$order) return false;

        $input = new WxPayRefund();
        $input->SetOut_trade_no($order['order_sn']);             //自己的订单号
        $input->SetTransaction_id($order['transaction_id']);     //微信官方生成的订单流水号，在支付成功中有返回
        $input->SetOut_trade_no($order['out_trade_no']);
        $input->SetOut_refund_no(getrand_num(true));            //退款单号
        $input->SetTotal_fee($order['pay_price']*100);             //订单标价金额，单位为分
        $input->SetRefund_fee($order['pay_price']*100);            //退款总金额，订单总金额，单位为分，只能为整数
        $input->SetOp_user_id($merchid);




        $result = WxPayApi::refund($input); //退款操作

        // 这句file_put_contents是用来查看服务器返回的退款结果 测试完可以删除了
        //file_put_contents(APP_ROOT.'/Api/wxpay/logs/log3.txt',arrayToXml($result),FILE_APPEND);
        return $result;
    }

    /** 小程序支付
     * @param $order
     * @param $openId
     * @return json数据，可直接填入js函数作为参数
     */
    function getJSAPI_wxmini($order,$openId)
    {

        WxPayConfig::$appid = 'wxb28fa3d978402d82'; // * 小程序appid
        WxPayConfig::$mchid = '1500022962'; // * MCHID：商户号（必须配置，开户邮件中可查看）
        WxPayConfig::$key = 'HrtJBvBG5zmBFOE0hfWV4vmyf8oc99li'; // KEY：商户支付密钥，参考开户邮件设置（必须配置，登录商户平台自行设置）
        WxPayConfig::$appsecret = 'd9afd8de746b08b6e8a1746daffe77dd'; // 小程序secert ，

        //①、获取用户openid
        $tools = new JsApiPay();
        //$openId = $tools->GetOpenid();
//        $openId = $_SESSION['openid'];//公众号（改成小程序）
        //②、统一下单
        $input = new WxPayUnifiedOrder();
        $input->SetBody("支付订单：" . $order['order_sn']);
        $input->SetAttach("weixin");
        $input->SetOut_trade_no($order['order_sn'] . time());
        $input->SetTotal_fee($order['pay_price'] * 100);
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 600));
        $input->SetGoods_tag("tp_wx_pay");
        //$input->SetNotify_url(SITE_URL.'/index.php/Home/Payment/notifyUrl/pay_code/weixin');
        $input->SetNotify_url(SITE_URL . '/Mobile/Payment/notifyUrl/pay_code/weixin');
        $input->SetTrade_type("JSAPI");
        $input->SetOpenid($openId);
        $order2 = WxPayApi::unifiedOrder($input);


        /* echo '<font color="#f00"><b>统一下单支付单信息</b></font><br/>';*/
        $jsApiParameters = $tools->GetJsApiParameters($order2);
//        exit($jsApiParameters);
        return $jsApiParameters;
    }




    /**  微信H5支付
     * @param $amount
     * @param $wx_config
     * @param $order_sn
     * @return mixed
     */
    function get_H5_code($amount,$wx_config,$order_sn){
        /*h5微信支付*/
        $money= $amount*100;
        $userip = $_SERVER["REMOTE_ADDR"]; //获得用户设备IP 自己网上百度去
        $appid = $wx_config['appid'];//公众号appid
        $mch_id = $wx_config['mch_id'];//商户号
        $key = $wx_config['key'];//密钥
        $rand = rand(00000,99999);
        $out_trade_no = $order_sn;//平台内部订单号
        $nonce_str=MD5($rand);//随机字符串
        $body = "H5支付";//内容
        $total_fee = $money; //金额
        $spbill_create_ip = $userip; //IP
        $notify_url = SITE_URL.'/index.php/Mobile/Payment/notifyUrl/pay_code/weixin'; // 接收微信支付异步通知回调地址，通知url必须为直接可访问的url，不能携带参数。
        $trade_type = 'MWEB';//交易类型 具体看API 里面有详细介绍
        $scene_info ='{"h5_info":{"type":"Android","app_name":"朋伴网店交易","package_name":"com.kingkr.kyevqmk"}}';//安卓
        $signA ="appid=$appid&body=$body&mch_id=$mch_id&nonce_str=$nonce_str&notify_url=$notify_url&out_trade_no=$out_trade_no&scene_info=$scene_info&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type";
        $strSignTmp = $signA."&key=$key"; //拼接字符串  注意顺序微信有个测试网址 顺序按照他的来 直接点下面的校正测试 包括下面XML  是否正确
        $sign = strtoupper(MD5($strSignTmp)); // MD5 后转换成大写
        $post_data = "<xml><appid>$appid</appid><body>$body</body><mch_id>$mch_id</mch_id><nonce_str>$nonce_str</nonce_str><notify_url>$notify_url</notify_url><out_trade_no>$out_trade_no</out_trade_no><scene_info>$scene_info</scene_info><spbill_create_ip>$spbill_create_ip</spbill_create_ip><total_fee>$total_fee</total_fee><trade_type>$trade_type</trade_type><sign>$sign</sign></xml>";//拼接成XML 格式
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信传参地址
        $dataxml = $this->http_post($url,$post_data);//传参调用curl请求
//        $dataxml = http_post($url,$post_data,$headers);//传参调用curl请求
        $objectxml = (array)simplexml_load_string($dataxml,'SimpleXMLElement',LIBXML_NOCDATA); //将微信返回的XML 转换成数组
        $mweb_url = $objectxml["mweb_url"];

        return $mweb_url;
    }


//    function getIp(){
//        $ip = '';
//        if(isset($_SERVER['REMOTE_ADDR'])){
//            $ip = $_SERVER['REMOTE_ADDR'];
//        }elseif(getenv(REMOTE_ADDR)){
//            $ip =getenv(REMOTE_ADDR);
//        }
//        return $ip;
//    }

    function getIp(){
        if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'),'unknown')) {

            $ip = getenv('HTTP_CLIENT_IP');

        } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'),'unknown')) {

            $ip = getenv('HTTP_X_FORWARDED_FOR');

        } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'),'unknown')) {

            $ip = getenv('REMOTE_ADDR');

        } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {

            $ip = $_SERVER['REMOTE_ADDR'];

        }

        return preg_match ( '/[\d\.]{7,15}/', $ip, $matches ) ? $matches [0] : '';
    }

    function http_post($url='',$post_data=array(),$header=array(),$timeout=30) {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_URL, $url);
        //curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);

        $response = curl_exec($ch);

        curl_close($ch);

        return $response;
    }


    /**
     * 生成支付代码
     * @param   array   $order      订单信息
     * @param   array   $config_value    支付方式信息
     */
    function get_code($order, $config_value)
    {
        $notify_url = SITE_URL.'/Home/Payment/notifyUrl/pay_code/weixin'; // 接收微信支付异步通知回调地址，通知url必须为直接可访问的url，不能携带参数。
        //$notify_url = C('site_url').U('Home/Payment/notifyUrl',array('pay_code'=>'weixin')); // 接收微信支付异步通知回调地址，通知url必须为直接可访问的url，不能携带参数。
        //$notify_url = C('site_url')."/index.php?m=Home&c=Payment&a=notifyUrl&pay_code=weixin";

        $input = new WxPayUnifiedOrder();
        $input->SetBody("朋伴网店订单"); // 商品描述
        $input->SetAttach("weixin"); // 附加数据，在查询API和支付通知中原样返回，该字段主要用于商户携带订单的自定义数据
        $input->SetOut_trade_no($order['order_sn'].time()); // 商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
        $input->SetTotal_fee($order['pay_price']*100); // 订单总金额，单位为分，详见支付金额
        $input->SetNotify_url($notify_url); // 接收微信支付异步通知回调地址，通知url必须为直接可访问的url，不能携带参数。
        $input->SetTrade_type("NATIVE"); // 交易类型   取值如下：JSAPI，NATIVE，APP，详细说明见参数规定    NATIVE--原生扫码支付
        $input->SetProduct_id("123456789"); // 商品ID trade_type=NATIVE，此参数必传。此id为二维码中包含的商品ID，商户自行定义。
        $notify = new NativePay();
        $result = $notify->GetPayUrl($input); // 获取生成二维码的地址
        $url2 = $result["code_url"];
//            return '<img alt="模式二扫码支付" src="/index.php?m=Home&c=Index&a=qr_code&data='.urlencode($url2).'" style="width:110px;height:110px;"/>';
        return '<img alt="模式二扫码支付" src="/index.php?m=Home&c=Index&a=qr_code&data='.urlencode($url2).'" style="width:200px;height:200px;"/>';
    }
    /**
     * 服务器点对点响应操作给支付接口方调用
     *
     */
    function response()
    {

        require_once("example/notify.php");
        $notify = new PayNotifyCallBack();
        $notify->Handle(false);
    }

    /**
     * 页面跳转响应操作给支付接口方调用
     */
    function respond2()
    {
        // 微信扫码支付这里没有页面返回
    }

    function getJSAPI($order){
        if(stripos($order['order_sn'],'recharge') !== false){
            $go_url = U('Mobile/User/points',array('type'=>'recharge'));
            $back_url = U('Mobile/User/recharge',array('order_id'=>$order['order_id']));
        }else{
            $go_url = U('Mobile/User/order_detail',array('id'=>$order['order_id']));
            //$back_url = U('Mobile/Cart/cart4',array('order_id'=>$order['order_id']));
            $back_url = U('Mobile/User/order_list/type/WAITPAY');
        }
        //①、获取用户openid
        $tools = new JsApiPay();
        //$openId = $tools->GetOpenid();
        $openId = $_SESSION['openid'];
        //②、统一下单
        $input = new WxPayUnifiedOrder();
        $input->SetBody("支付订单：".$order['order_sn']);
        $input->SetAttach("weixin");
        $input->SetOut_trade_no($order['order_sn'].time());
        $input->SetTotal_fee($order['pay_price']*100);
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 600));
        $input->SetGoods_tag("tp_wx_pay");
        //$input->SetNotify_url(SITE_URL.'/index.php/Home/Payment/notifyUrl/pay_code/weixin');
        $input->SetNotify_url(SITE_URL.'/Home/Payment/notifyUrl/pay_code/weixin');
        $input->SetTrade_type("JSAPI");
        $input->SetOpenid($openId);
        $order2 = WxPayApi::unifiedOrder($input);
        //echo '<font color="#f00"><b>统一下单支付单信息</b></font><br/>';
        //printf_info($order);exit;
        $jsApiParameters = $tools->GetJsApiParameters($order2);
        $html = <<<EOF
	<script type="text/javascript">
	//调用微信JS api 支付
	function jsApiCall()
	{ 
		WeixinJSBridge.invoke(
			'getBrandWCPayRequest',$jsApiParameters,
			function(res){
				 if(res.err_msg == "get_brand_wcpay_request:ok") {
				    location.href='$go_url';
				 }else{
				 	//alert(res.err_code+res.err_desc+res.err_msg);
				    location.href='$back_url';
				 }
			}
		);
	}

	function callpay()
	{
		if (typeof WeixinJSBridge == "undefined"){
		    if( document.addEventListener ){
		        document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
		    }else if (document.attachEvent){
		        document.attachEvent('WeixinJSBridgeReady', jsApiCall);
		        document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
		    }
		}else{
		    jsApiCall();
		}
	}
	callpay();
	</script>
EOF;

        return $html;

    }

}